package master;

import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import nfeitens.NfeItens;

/**
 *
 * @author camilo
 */
public class NfeItensTableModel extends AbstractTableModel {

  private static final long serialVersionUID = 1L;
  /**
   * Essa lista armazenará os objetos do tipo {@link NfeItens} atualmente exibidos na tabela.
   */
  private List<NfeItens> nfei;

  // ==============================================================  
  // Construtores.  
  // ==============================================================  
  /**
   * Constutor que simplesmente instancia o nosso {@link List} que usaremos para guardar os valores.
   */
  public NfeItensTableModel() {
    // no construtor, instanciamos o List  
    nfei = new ArrayList<NfeItens>();
  }

  /**
   * Criamos um construtor de conveniência para já popular a lista.
   *
   * @param lista a lista de produtos a ser adicionada.
   */
  public NfeItensTableModel(List<NfeItens> lista) {
    this();
    nfei.addAll(lista);
  }

  // ==============================================================  
  // Métodos implementados.  
  // ==============================================================  
  @Override
  public Class<?> getColumnClass(int coluna) {
    // todas as colunas representam uma String  
    return String.class;
  }

  @Override
  public int getColumnCount() {
    // esse método deve retornar o número de colunas. No caso, 3 (uma para o  
    // nome, uma para o sobrenome e uma para o apelido).  
    return 17;
  }

  @Override
  public String getColumnName(int coluna) {
    // vamos retornar o nome de cada coluna  
    switch (coluna) {
      case 0:
        return "Nº"; // o nome da primeira coluna  
      case 1:
        return "Prod"; // o nome da segunda  
      case 2:
        return "EAN"; // e o da terceira  
      case 3:
        return "Descrição"; // e o da terceira  
      case 4:
        return "CFOP"; // e o da terceira  
      case 5:
        return "CST"; // e o da terceira  
      case 6:
        return "MVA"; // e o da terceira  
      case 7:
        return "Qtd"; // e o da terceira  
      case 8:
        return "Acom"; // e o da terceira  
      case 9:
        return "V.Un"; // e o da terceira  
      case 10:
        return "Ref"; // e o da terceira  
      case 11:
        return "ICMS"; // e o da terceira  
      case 12:
        return "Red."; // e o da terceira  
      case 13:
        return "vICMS"; // e o da terceira  
      case 14:
        return "IPI"; // e o da terceira  
      case 15:
        return "vIPI"; // e o da terceira  
      case 16:
        return "Total"; // e o da terceira
      default:
        return ""; // isso nunca deve ocorrer, pois temos só 3 colunas  
    }
  }

  @Override
  public int getRowCount() {
    // retorna o número de linhas, ou seja, a quantidade de entradas na nossa lista.  
    return nfei.size();
  }

  @Override
  public Object getValueAt(int linha, int coluna) {
    // vai retornar o valor de determinada célula. A linha representa a  
    // posição do Cliente na nossa lista e a coluna vai ser: 1 - nome, 2 -  
    // sobrenome e 3 - apelido  
    // primeiro vamos pegar o Cliente da linha  
    NfeItens nf = nfei.get(linha);
    // façamos um switch  
    switch (coluna) {
      case 0:
        return nf.getItem(); // o nome da primeira coluna  
      case 1:
        return nf.getProduto(); // o nome da segunda  
      case 2:
        return nf.getBarras(); // e o da terceira  
      case 3:
        return nf.getDescricao(); // e o da terceira  
      case 4:
        return nf.getCfop(); // e o da terceira  
      case 5:
        return nf.getCst(); // e o da terceira  
      case 6:
        return nf.getMva(); // e o da terceira  
      case 7:
        return nf.getQuantidade(); // e o da terceira  
      case 8:
        return nf.getAcomodacao(); // e o da terceira  
      case 9:
        return nf.getValorUnitario(); // e o da terceira  
      case 10:
        return nf.getRef(); // e o da terceira  
      case 11:
        return nf.getIcms(); // e o da terceira  
      case 12:
        return nf.getRedIcms(); // e o da terceira  
      case 13:
        return nf.getValorIcms(); // e o da terceira  
      case 14:
        return nf.getIpi(); // e o da terceira  
      case 15:
        return nf.getValorIpi(); // e o da terceira  
      case 16:
        return nf.getValorTotal(); // e o da terceira
      default:
        return null; // isso nunca deve ocorrer, pois temos só 3 colunas  
    }
  }

  @Override
  public boolean isCellEditable(int rowIndex, int columnIndex) {
    // nesse caso, todas as células são editáveis  
    return true;
  }

  @Override
  public void setValueAt(Object valor, int linha, int coluna) {
    // aqui devemos atualizar o valor de nossos Clientes  
    // vemos em qual linha ele está  
    NfeItens nf = nfei.get(linha);
    // e vemos o que será atualizado
    switch (coluna) {
      case 0:
        nf.setItem(valor.toString()); // mudamos o nome  
        break;
      case 1:
        nf.setProduto(Integer.parseInt(valor.toString()));
        break;
      case 2:
        nf.setBarras(valor.toString()); // e o da terceira
        break;
      case 3:
        nf.setDescricao(valor.toString()); // e o da terceira  
        break;
      case 4:
        nf.setCfop(valor.toString()); // e o da terceira  
        break;
      case 5:
        nf.setCst(valor.toString()); // e o da terceira  
        break;
      case 6:
        nf.setMva(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 7:
        nf.setQuantidade(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 8:
        nf.setAcomodacao(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 9:
        nf.setValorUnitario(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 10:
        nf.setRef(valor.toString()); // e o da terceira  
        break;
      case 11:
        nf.setIcms(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 12:
        nf.setRedIcms(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 13:
        nf.setValorIcms(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 14:
        nf.setIpi(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 15:
        nf.setValorIpi(Float.parseFloat(valor.toString())); // e o da terceira  
        break;
      case 16:
        nf.setValorTotal(Float.parseFloat(valor.toString())); // e o da terceira
        break;
    }
    // é importante notificar os listeners a cada alteração  
    fireTableDataChanged();
  }

  // ==============================================================  
  // Até aqui seria o mínimo necessário para um TableModel funcional, mas  
  // ainda não há métodos para adicionar, remover ou resgatar objetos. Vamos  
  // criá-los.  
  // ==============================================================  
  /**
   * Adiciona um novo {@link Cliente} e notifica os listeners que um novo registro foi adicionado.
   */
  public void adiciona(NfeItens nf) {
    nfei.add(nf);
    // informamos os listeners que a linha (size - 1) foi adicionada  
    fireTableRowsInserted(nfei.size() - 1, nfei.size() - 1);
  }

  /**
   * Similar ao {@link #adiciona(Cliente)}, porém para remover. Recebe o índice do cliente a ser removido. Se
   * não souber o índice, use o método {@link #getIndice(Cliente)} antes.
   */
  public void remove(int indice) {
    nfei.remove(indice);
    fireTableRowsDeleted(indice, indice);
  }

  /**
   * Retorna o índice de determinado cliente.
   */
  public int getIndice(NfeItens nf) {
    return nfei.indexOf(nf);
  }

  /**
   * Adiciona todos os clientes na lista à este modelo.
   */
  public void adicionaLista(List<NfeItens> lista) {
    int i = nfei.size();
    nfei.addAll(lista);
    fireTableRowsInserted(i, i + lista.size());
  }

  /**
   * Esvazia a lista.
   */
  public void limpaLista() {
    int i = nfei.size();
    nfei.clear();
    fireTableRowsDeleted(0, i - 1);
  }
}
